<template>
  <a-modal
    v-model:visible="visible"
    :title="title"
    :mask-closable="false"
    :esc-to-close="false"
    :modal-style="{ maxWidth: '620px' }"
    width="90%"
    @before-ok="save"
    @close="reset"
  >
    <GiForm ref="formRef" v-model="form" :options="options" :columns="columns" />
  </a-modal>
</template>

<script setup lang="ts">
import { Message, type RequestOption } from '@arco-design/web-vue'
import type { FileItem } from '@arco-design/web-vue/es/upload/interfaces'
import { addSoftware, getSoftware, updateSoftware } from '@/apis/vending/software'
import type { Columns, GiForm, Options } from '@/components/GiForm'
import { useForm } from '@/hooks'
import { useDict } from '@/hooks/app'
import { uploadFile } from '@/apis'

const emit = defineEmits<{
  (e: 'save-success'): void
}>()

const dataId = ref('')
const isUpdate = computed(() => !!dataId.value)
const title = computed(() => (isUpdate.value ? '修改软件版本' : '新增软件版本'))
const formRef = ref<InstanceType<typeof GiForm>>()

const { software_type } = useDict('software_type')

const options: Options = {
  form: {},
  btns: { hide: true },
}

const { form, resetForm } = useForm({
  status: 1,
  softwareType: 1,
  url: undefined,
})

const columns: Columns = reactive([
  {
    label: '软件名称',
    field: 'softwareName',
    type: 'input',
    rules: [{ required: true, message: '请输入软件名称' }],
  },
  {
    label: '版本名',
    field: 'versionName',
    type: 'input',
    rules: [{ required: true, message: '请输入软件版本名' }],
  },
  {
    label: '版本号',
    field: 'versionCode',
    type: 'input-number',
    props: {
      min: 1,
    },
    rules: [{ required: true, message: '请输入软件版本号' }],
  },
  {
    label: '软件描述',
    field: 'description',
    type: 'textarea',
    props: {
      maxLength: 200,
      showWordLimit: true,
    },
  },
  {
    label: '软件类型',
    field: 'softwareType',
    type: 'radio-group',
    options: software_type,
    rules: [{ required: true, message: '请输入软件类型' }],
  },
  {
    label: '状态',
    field: 'status',
    type: 'switch',
    props: {
      type: 'round',
      defaultChecked: true,
      checkedValue: 1,
      uncheckedValue: 2,
      checkedText: '启用',
      uncheckedText: '禁用',
    },
  },
  {
    type: 'upload',
    label: '软件包',
    field: 'file',
    props: {
      listType: 'text',
      limit: 1,
      accept: 'file/apk,file/rar',
      customRequest: (options: RequestOption) => {
        const controller = new AbortController()
        ;(async function requestWrap() {
          const { onProgress, onError, onSuccess, fileItem, name = 'file' } = options
          onProgress(20)
          const formData = new FormData()
          formData.append(name as string, fileItem.file as Blob)
          try {
            const res = await uploadFile(formData)
            Message.success('上传成功')
            onSuccess(res)
          } catch (error) {
            onError(error)
          }
        })()
        return {
          abort() {
            controller.abort()
          },
        }
      },
      onSuccess: (fileItem: FileItem) => {
        if (!form.softwareName) {
          form.softwareName = fileItem.name
        }
        form.url = fileItem.response.data.url
      },
    },
    formItemProps: {
      extra: '上传文件只支持apk、rar格式',
    },
  },
])

// 重置
const reset = () => {
  formRef.value?.formRef?.resetFields()
  resetForm()
}

const visible = ref(false)
// 新增
const onAdd = () => {
  reset()
  dataId.value = ''
  visible.value = true
}

// 修改
const onUpdate = async (id: string) => {
  reset()
  dataId.value = id
  const res = await getSoftware(id)
  Object.assign(form, res.data)
  visible.value = true
}

// 保存
const save = async () => {
  try {
    if (!form.url) {
      Message.error('请选择文件')
      return false
    }
    const isInvalid = await formRef.value?.formRef?.validate()
    if (isInvalid) return false
    if (isUpdate.value) {
      await updateSoftware(form, dataId.value)
      Message.success('修改成功')
    } else {
      await addSoftware(form)
      Message.success('新增成功')
    }
    emit('save-success')
    return true
  } catch (error) {
    return false
  }
}

defineExpose({ onAdd, onUpdate })
</script>
